package br.unifor.cct.mia.ga.coevolutionary;

import java.io.IOException;
import java.util.List;

import br.unifor.cct.mia.coevolution.CoevolutionaryDomain;
import br.unifor.cct.mia.dataenhancement.Database;
import br.unifor.cct.mia.dataenhancement.Structure;
import br.unifor.cct.mia.dataenhancement.Tuple;
import br.unifor.cct.mia.evolutionary.Genotype;
import br.unifor.cct.mia.evolutionary.SpeciesConstants;
import br.unifor.cct.mia.ga.Ga;
import br.unifor.cct.mia.util.SaveReport;

public class CoevGaMV extends Ga {
    
	private Structure structure;
	private Database dbOriginal;
	private List positions;	
	private Tuple tuples;
	private CoevolutionaryDomain domain;
	private Integer specieType = new Integer(SpeciesConstants.MISSING_VALUE);	
	
    private static String[] configuracoes = {
    		"br.unifor.cct.mia.xover.XOverOriginal",
			"br.unifor.cct.mia.select.MinimizeRoulette",
			"br.unifor.cct.mia.coevolution.evaluate.CoevolutionaryEvaluation",
			"br.unifor.cct.mia.mutation.MutationOriginal",
			"br.unifor.cct.mia.initialize.RandomInitialize"
    };    
 
    
    public CoevGaMV(Structure structure, Database dbOriginal, CoevolutionaryDomain domain, List positions, int nVars, Tuple tuples, String[] options) {
    	super(nVars, configuracoes,options);
    	System.out.println("Iniciando populacao de Missing Value");
    	this.domain = domain;
    	this.structure = structure;
    	this.dbOriginal = dbOriginal;
    	this.positions = positions;
    	this.tuples = tuples;
    }
    
    protected void elitist() {
    	super.elitist();	    	
    }
    
    public Object[] getObjectsMutate() {
		Object[] o = new Object[1];
		o[0] = this;
		return o;
	}

	public Object[] getObjectsSelect() {
		Object[] o = new Object[1];
		o[0] = this;
		return o;
	}

	public Object[] getObjectsEvaluate() {
		Object[] o = new Object[7];
		o[0] = domain;
		o[1] = specieType;
		o[2] = structure;
		o[3] = dbOriginal;
		o[4] = this;
		o[5] = tuples;
		o[6] = positions;
		return o;
	}
	
	public Object[] getObjectsCrossover() {
		Object[] o = new Object[1];
		o[0] = this;
		return o;
	}

	public Object[] getObjectsInitialize() {
        Object[] o = new Object[3];
        o[0] = positions;
        o[1] = structure;
        o[2] = this;
		return o;
	}
	
    protected void gravarBase() {	
		try {
			SaveReport report = new SaveReport("temp/result.txt",structure.getStrucFile());
			report.addLine(tuples.string(structure.getStringValues(positions, ((Genotype)population[configurations.getPopsize()]).getGene())));
			report.saveToDisk();			

			Database dbAuxHidden = (Database)dbOriginal.clone();
			dbAuxHidden.updateValues(positions,structure);					
			SaveReport report2 = new SaveReport("temp/resultHidden.txt",structure.getStrucFile());
			report2.addLine(dbAuxHidden.toString());
			report2.saveToDisk();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
    }        
	
	public Integer getSpecieType() {
		return specieType;
	}

	public void setSpecieType(Integer specieType) {
		this.specieType = specieType;
	}
}